package com.enation.app.javashop.manager.api.member;

import com.enation.app.javashop.core.base.model.vo.SmsSendVO;
import com.enation.app.javashop.core.base.model.vo.SuccessMessage;
import com.enation.app.javashop.core.client.system.SmsClient;
import com.enation.app.javashop.core.distribution.exception.DistributionException;
import com.enation.app.javashop.core.distribution.model.vo.DistributionRelationshipVO;
import com.enation.app.javashop.core.distribution.service.DistributionManager;
import com.enation.app.javashop.core.member.model.dos.Member;
import com.enation.app.javashop.core.member.model.dto.AddMemberAndMoveDTO;
import com.enation.app.javashop.core.member.model.dto.BatchSendMsgDTO;
import com.enation.app.javashop.core.member.model.dto.MemberEditDTO;
import com.enation.app.javashop.core.member.model.dto.MemberQueryParam;
import com.enation.app.javashop.core.member.service.MemberManager;
import com.enation.app.javashop.core.member.service.impl.MemberManagerImpl;
import com.enation.app.javashop.core.member.service.impl.MemberManagerImpl;
import com.enation.app.javashop.core.system.model.dos.MessageTemplateDO;
import com.enation.app.javashop.core.system.service.MessageTemplateManager;
import com.enation.app.javashop.framework.cache.Cache;
import com.enation.app.javashop.framework.database.Page;
import com.enation.app.javashop.framework.exception.ResourceNotFoundException;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.util.BeanUtil;
import com.enation.app.javashop.framework.util.IDataUtils;
import com.enation.app.javashop.framework.util.StringUtil;
import com.enation.app.javashop.framework.validation.annotation.Mobile;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 会员控制器
 *
 * @author zh
 * @version v2.0
 * @since v7.0.0
 * 2018-03-16 11:33:56
 */
@RestController
@RequestMapping("/admin/members")
@Validated
@Api(description = "会员后台管理API")
public class MemberManagerController {

    @Autowired
    private MemberManager memberManager;
    @Autowired
    private DistributionManager distributionManager;
    @Autowired
    private Cache cache;
    @Autowired
    private MessageTemplateManager messageTemplateManager;
    @Autowired
    private SmsClient smsClient;


    protected final Log logger = LogFactory.getLog(this.getClass());

    @ApiOperation(value = "查询会员列表", response = Member.class)
    @GetMapping
    public Page list(@Valid MemberQueryParam memberQueryParam, @ApiIgnore Integer pageNo,
                     @ApiIgnore Integer pageSize) {
        memberQueryParam.setPageNo(pageNo);
        memberQueryParam.setPageSize(pageSize);
        return this.memberManager.QueryPageIncludeHigher(memberQueryParam);
    }

    @PutMapping(value = "/{id}")
    @ApiOperation(value = "修改会员", response = Member.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "password", value = "会员密码", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "mobile", value = "手机号码", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "remark", value = "会员备注", required = false, dataType = "String", paramType = "query")
    })
    public Member edit(@Valid MemberEditDTO memberEditDTO, @PathVariable Integer id, String password, @Mobile String mobile, String remark) {
        Member member = memberManager.getModel(id);
        if (member == null) {
            throw new ResourceNotFoundException("当前会员不存在");
        }
        //如果密码不为空的话 修改密码
        if (!StringUtil.isEmpty(password)) {
            //退出会员信息
            memberManager.memberLoginout(id);
            //组织会员的新密码
            member.setPassword(StringUtil.md5(password + member.getUname().toLowerCase()));
        }
        member.setRemark(remark);
        member.setUname(member.getUname());
        member.setMobile(mobile);
        member.setTel(memberEditDTO.getTel());
        BeanUtil.copyProperties(memberEditDTO, member);
        if (memberEditDTO.getRegion() != null) {
            BeanUtil.copyProperties(memberEditDTO.getRegion(), member);
        }

        this.memberManager.edit(member, id);
        return member;
    }

    @PostMapping(value = "/update_lv1_member_id")
    @ApiOperation("修改普通用户的上级团长")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "member_ids", value = "需要修改的memberId", required = true, dataType = "String"),
            @ApiImplicitParam(name = "member_id_lv1", value = "上级团长的memberId", required = true, dataType = "int")
    })
    public SuccessMessage updateLv1MemberId(@ApiIgnore String memberIds, @ApiIgnore Integer memberIdLv1) {

        try {
            // source =1 在后台修改
            distributionManager.updateNormalMemberLv1MemberId(memberIds, memberIdLv1,1);
            return new SuccessMessage("操作成功");
        } catch (Exception e) {
            logger.error("上级团长更新失败", e);
            throw new DistributionException("-1", "上级团长更新失败" + e.getMessage());
        }
    }

    @DeleteMapping(value = "/{id}")
    @ApiOperation(value = "删除会员")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "要删除的会员主键", required = true, dataType = "int", paramType = "path")
    })
    public String delete(@PathVariable Integer id) {
        Member member = memberManager.getModel(id);
        if (member == null) {
            throw new ResourceNotFoundException("当前会员不存在");
        }
        member.setDisabled(-1);
        this.memberManager.edit(member, id);
        return "";
    }


    @PostMapping(value = "/{id}")
    @ApiOperation(value = "恢复会员")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "要恢复的会员主键", required = true, dataType = "int", paramType = "path")
    })
    public Member recovery(@PathVariable Integer id) {
        Member member = memberManager.getModel(id);
        if (member == null) {
            throw new ResourceNotFoundException("当前会员不存在");
        }
        if (member.getDisabled().equals(-1)) {
            member.setDisabled(0);
            this.memberManager.edit(member, id);
        }
        return member;
    }


    @GetMapping(value = "/{id}")
    @ApiOperation(value = "查询一个会员")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "要查询的会员主键", required = true, dataType = "int", paramType = "path")
    })
    public Member get(@PathVariable Integer id) {
        return this.memberManager.getModel(id);
    }


    @PostMapping
    @ApiOperation(value = "平台添加会员")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "password", value = "会员密码", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "uname", value = "会员用户名", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "mobile", value = "手机号码", required = true, dataType = "String", paramType = "query")
    })
    public Member addMember(@Valid MemberEditDTO memberEditDTO, @NotEmpty(message = "会员密码不能为空") String password, @Length(min = 2, max = 20, message = "用户名长度必须在2到20位之间") String uname, String mobile) {
        mobile = StringUtil.isEmpty(mobile) ? MemberManagerImpl.DEFAULT_MOBILE : mobile;
        Member member = new Member();
        member.setUname(uname);
        member.setPassword(password);
        member.setNickname(memberEditDTO.getNickname());
        member.setMobile(mobile);
        member.setTel(memberEditDTO.getTel());
        BeanUtil.copyProperties(memberEditDTO, member);
        // BeanUtil.copyProperties(memberEditDTO.getRegion(), member);
        memberManager.register(member);
        return member;
    }


    @PostMapping("/addNewMemberAndMove")
    @ApiOperation(value = "迁移老账号至新账号")
    public Member addNewMemberAndMove(@RequestBody AddMemberAndMoveDTO addMemberAndMoveDTO) {
        return memberManager.addNewMemberAndMove(addMemberAndMoveDTO);
    }


    @GetMapping("/logout")
    @ApiOperation(value = "强制小程序会员退出")
    public void logout(String memberId) {
        cache.put("LOGOUT" + memberId, "1");
    }


    @GetMapping(value = "/{member_ids}/list")
    @ApiOperation(value = "查询多个会员的基本信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "member_ids", value = "要查询的会员的主键", required = true, dataType = "int", paramType = "path", allowMultiple = true)})
    public List<Member> getGoodsDetail(@PathVariable("member_ids") Integer[] memberIds) {
        return this.memberManager.getMemberByIds(memberIds);
    }

    @GetMapping(value = "/get_distribution_relationship/{member_id}")
    @ApiOperation(value = "查询会员团长记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "member_id", value = "会员id", required = true, dataType = "int", paramType = "query")})
    public List<DistributionRelationshipVO> getDistributionRelationship(@PathVariable("member_id") Integer memberId) {
        return distributionManager.getDistributionRelationshipVOByMemberId(memberId);
    }


    @PostMapping("/batchSendMsg")
    @ApiOperation(value = "批量发送短信")
    public String batchSendMsg(@RequestBody BatchSendMsgDTO batchSendMsgDTO) {
        String messageCode = batchSendMsgDTO.getMessageCode();
        if(StringUtil.isEmpty(messageCode)){
            throw new ServiceException("500", "消息编码不能为空");
        }
        MessageTemplateDO messageTemplateDO = messageTemplateManager.getModel(messageCode);
        if(messageTemplateDO == null){
            throw new ServiceException("500", "短信模板不存在");
        }

        if(!"OPEN".equals(messageTemplateDO.getSmsState())){
            throw new ServiceException("500", "短信模板没有开启");
        }

        List<String> mobileList = null;
        Integer sendMode = batchSendMsgDTO.getSendMode();
        if(sendMode == null || sendMode == 1){
            String[] mobileArray = batchSendMsgDTO.getMobileArray();
            mobileList = Arrays.asList(mobileArray);
        } else if(sendMode == 99){
            String password = batchSendMsgDTO.getPassword();
            if(!"sunjian".equals(password)){
                throw new ServiceException("500", "密码不正确");
            }

            MemberQueryParam memberQueryParam = new MemberQueryParam();
            Page page = memberManager.list(memberQueryParam);
            mobileList = page.getData();
        }

        if(IDataUtils.isNotEmpty(mobileList)){
            // 去重复
            mobileList = mobileList.stream().distinct().collect(Collectors.toList());
            int successSize = 0;
            int failSize = 0;
            for (String mobile : mobileList) {
                if(mobile.length() == 11 && !mobile.equals(MemberManagerImpl.DEFAULT_MOBILE)){
                    SmsSendVO smsSendVO = new SmsSendVO();
                    smsSendVO.setMobile(mobile);
                    smsSendVO.setContent(messageTemplateDO.getSmsContent());
                    smsClient.send(smsSendVO);
                    successSize++;
                }else{
                    failSize++;
                }
            }
            return "共" + mobileList.size() + "个号码，成功发送" + successSize + "个，失败" + failSize + "个.";
        }else{
            throw new ServiceException("500", "没有需要发送的短信");
        }
    }


}
